package us.mooresr.webtroopmanager.client.ui;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

import us.mooresr.webtroopmanager.client.TroopManagerService;
import us.mooresr.webtroopmanager.client.TroopManagerServiceAsync;
import us.mooresr.webtroopmanager.client.place.UserListPlace;
import us.mooresr.webtroopmanager.client.ui.cells.PersonCell;
import us.mooresr.webtroopmanager.shared.PersonSummary;
import us.mooresr.webtroopmanager.shared.Role;
import us.mooresr.webtroopmanager.shared.User;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.uibinder.client.UiHandler;
import com.google.gwt.user.cellview.client.CellList;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.DialogBox;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.PasswordTextBox;
import com.google.gwt.user.client.ui.ScrollPanel;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.view.client.ListDataProvider;
import com.google.gwt.view.client.ProvidesKey;
import com.google.gwt.view.client.SelectionChangeEvent;
import com.google.gwt.view.client.SingleSelectionModel;

public class EditUserViewImpl extends Composite implements EditUserView {
	Presenter presenter;
	Long userId;
	ArrayList<Role> roles;
	CellList<PersonSummary> cellList;
	PersonSummary selectedPerson;
	ListDataProvider<PersonSummary> dataProvider;
	
	@UiField
	TextBox userNameTextBox;
	
	@UiField
	TextBox realNameTextBox;
	
	@UiField
	PasswordTextBox passwordTextBox;
	
	@UiField
	TextBox emailAddressTextBox;
	
	@UiField
	CheckBox enabledCheckBox;
	
	@UiField
	Button okButton;
	
	@UiField
	Button cancelButton;
	
	@UiField
	FlexTable roleGrid;
	
	@UiField
	Button addButton;
	
	@UiField
	Button removeButton;
	
	@UiField
	ScrollPanel personList;
	
	@UiHandler("cancelButton")
	void onCancel(ClickEvent e) {
		presenter.goTo(new UserListPlace());
	}
	
	@UiHandler("okButton")
	void onOk(ClickEvent e) {
		User newUser = new User(userId, userNameTextBox.getText(), passwordTextBox.getText(), realNameTextBox.getText(),
				emailAddressTextBox.getText());
		newUser.setEnabled(enabledCheckBox.getValue());
		
		newUser.clearRoles();
		for (int i=0; i<roles.size(); i++) {
			CheckBox cb = (CheckBox)roleGrid.getWidget(i, 0);
			if (cb.getValue() == true) {
				newUser.addRole(roles.get(i).getId());
			}
		}
		
		newUser.clearPersonIds();
		List<PersonSummary> personList = dataProvider.getList();
		for (PersonSummary p : personList) {
			newUser.addPerson(p.getId());
		}
		
		
		
		presenter.addUser(newUser);
		presenter.goTo(new UserListPlace());
		
	}
	
	@UiHandler("addButton")
	void onAdd(ClickEvent e) {
		AddPersonDialog dlg = new AddPersonDialog(presenter, this);
		dlg.show();
	}

	@UiHandler("removeButton")
	void onRemove(ClickEvent e) {
		List<PersonSummary> providerList = dataProvider.getList();
		providerList.remove(selectedPerson);
	}
	private static EditUserViewImplUiBinder uiBinder = GWT
			.create(EditUserViewImplUiBinder.class);

	interface EditUserViewImplUiBinder extends
			UiBinder<Widget, EditUserViewImpl> {
	}

	public EditUserViewImpl() {
		initWidget(uiBinder.createAndBindUi(this));
		
		ProvidesKey<PersonSummary> keyProvider = new ProvidesKey<PersonSummary>() {
			public Object getKey(PersonSummary item) {
				return (item == null) ? null : item.getId();
			}
		};
		cellList = new CellList<PersonSummary>(new PersonCell(), keyProvider);

		cellList.setSize("292px", "172px");
		
		final SingleSelectionModel<PersonSummary> selectionModel = new SingleSelectionModel<PersonSummary>(keyProvider);
		cellList.setSelectionModel(selectionModel);
		selectionModel.addSelectionChangeHandler(new SelectionChangeEvent.Handler() {

			@Override
			public void onSelectionChange(SelectionChangeEvent event) {
				selectedPerson = selectionModel.getSelectedObject();
				if (selectedPerson == null) {
					// Disable buttons that act on a selected person
					removeButton.setEnabled(false);
				} else {
					// Enable buttons that act on a selected person
					removeButton.setEnabled(true);
				}
						
			}
			
		});
		
		dataProvider = new ListDataProvider<PersonSummary>();
		dataProvider.addDataDisplay(cellList);
		
		personList.setWidget(cellList);
		cellList.setSize("100%", "100%");
		
		removeButton.setEnabled(false);

		
	}

	
	public void setPresenter(Presenter presenter) {
		this.presenter = presenter;
	}

	@Override
	public void setData(User user) {
		List<PersonSummary> providerList = dataProvider.getList();
		providerList.clear();
		
		if (user == null) {
			userId = null;
			userNameTextBox.setText("");
			realNameTextBox.setText("");
			emailAddressTextBox.setText("");
			passwordTextBox.setText("");
			enabledCheckBox.setValue(false);
		} else {
			userId = user.getUserId();
			userNameTextBox.setText(user.getUserName());
			realNameTextBox.setText(user.getRealName());
			emailAddressTextBox.setText(user.getEmailAddress());
			enabledCheckBox.setValue(user.getEnabled());
			passwordTextBox.setText("");
			
			Set<Long> userRoles = user.getRoleIds();
			if (userRoles != null) {
				for (int i=0; i<roles.size(); i++) {
					if (userRoles.contains(roles.get(i).getId())) {
						CheckBox c = (CheckBox)roleGrid.getWidget(i, 0);
						c.setValue(true);
					}
				}
			}
		}
		
		
	}
	
	@Override
	public void setRoles(List<Role> roles) {
		// Save our list of roles - we'll want it later
		this.roles = new ArrayList<Role>(roles.size());
		for (Role r : roles) {
			this.roles.add(r);		
		}
		
		// Clear the FlexTable
		for (int i=0; i<roleGrid.getRowCount(); i++) {
			roleGrid.removeRow(0);
		}
		
		// Add all the possible roles to the FlexTable
		for (int i=0; i<roles.size(); i++) {
			roleGrid.setWidget(i, 0, new CheckBox(roles.get(i).getRoleName()));
		}
	}
	
	@Override
	public void setPeople(List<PersonSummary> people) {
		List<PersonSummary> providerList = dataProvider.getList();
		
		if (people == null) {
			return;
		}
		
		for (PersonSummary p : people) {
			providerList.add(p);
		}
		cellList.setPageSize(people.size());
	}
	
	private void addPerson(PersonSummary person) {
		List<PersonSummary> providerList = dataProvider.getList();
		
		providerList.add(person);
		
		
	}

	private static class AddPersonDialog extends DialogBox {
		EditUserView.Presenter presenter;
		CellList<PersonSummary> cellList;
		PersonSummary selectedPerson;
		
		
		
		public AddPersonDialog(final Presenter presenter, final EditUserViewImpl view) {
			
			this.presenter = presenter; 
			
			setText("Select Person");
			
			ScrollPanel scrollPanel = new ScrollPanel();
			PersonCell personCell = new PersonCell();
			cellList = new CellList<PersonSummary>(personCell);
			cellList.setSize("200px", "300px");
			
			
			FlexTable grid = new FlexTable();
			Button okButton = new Button("OK");
			Button cancelButton = new Button("Cancel");
			
			scrollPanel.setWidget(cellList);
			
			grid.setWidget(0, 0, scrollPanel);
			grid.getFlexCellFormatter().setColSpan(0, 0,2);
			grid.setWidget(1, 0, okButton);
			grid.setWidget(1, 1, cancelButton);
			setWidget(grid);
			
			// Add a selection model to handle user selection.
		    final SingleSelectionModel<PersonSummary> selectionModel = new SingleSelectionModel<PersonSummary>();
		    cellList.setSelectionModel(selectionModel);
		    selectionModel.addSelectionChangeHandler(new SelectionChangeEvent.Handler() {
		      public void onSelectionChange(SelectionChangeEvent event) {
		    	  selectedPerson = selectionModel.getSelectedObject();
		      }
		    });

			
			okButton.addClickHandler(new ClickHandler() {
				@Override
				public void onClick(ClickEvent event) {
					view.addPerson(selectedPerson);
					hide();
					
				}		
			});
			
			cancelButton.addClickHandler(new ClickHandler() {
				@Override
				public void onClick(ClickEvent event) {
					hide();
					
				}		
			});
			
			TroopManagerServiceAsync troopManagerService = (TroopManagerServiceAsync) GWT.create(TroopManagerService.class);
			
			
			AsyncCallback<List<PersonSummary>> callback = new AsyncCallback<List<PersonSummary>>() {

				@Override
				public void onFailure(Throwable caught) {
					// TODO Auto-generated method stub
					
				}

				@Override
				public void onSuccess(List<PersonSummary> result) {
					cellList.setRowCount(result.size());
					cellList.setRowData(0, result);
					
				}
			};

			troopManagerService.getAllPeople(callback);
		}
		
		
	}
}
